package cn.yunyichina.provider.order.service.impl;

import cn.yunyichina.provider.framework.common.PKGenerator;
import cn.yunyichina.provider.framework.dubbo.service.*;
import cn.yunyichina.provider.framework.utils.UUIDUtil;
import cn.yunyichina.provider.iface.entity.base.OrderExtVo;
import cn.yunyichina.provider.iface.entity.base.RoleVo;
import cn.yunyichina.provider.iface.entity.common.ResCommon;
import cn.yunyichina.provider.iface.entity.common.Response;
import cn.yunyichina.provider.iface.entity.hisiface.bed.DepositRecordsVo;
import cn.yunyichina.provider.iface.entity.hisiface.bed.DepositRecordsVoResponse;
import cn.yunyichina.provider.iface.entity.hisiface.clinic.PayVo;
import cn.yunyichina.provider.iface.entity.hisiface.clinic.PayVoResponse;
import cn.yunyichina.provider.iface.entity.hisiface.register.RegisterExceptionRecordVo;
import cn.yunyichina.provider.iface.entity.hisiface.register.RegisterExceptionRecordVoResponse;
import cn.yunyichina.provider.order.dao.OrderRefundValidateDao;
import cn.yunyichina.provider.order.entity.OrderRefundValidate;
import cn.yunyichina.utils.commons.DateUtils;
import cn.yunyichina.utils.convert.JsonUtils;
import cn.yunyichina.utils.convert.ObjectParser;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.qiniu.util.Json;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * Created by Administrator on 2017/11/23.
 */
@Service
public class RefundServiceImpl {
    private static Logger logger = LoggerFactory.getLogger(RefundServiceImpl.class);

    @Autowired
    private OrderRefundValidateDao orderRefundValidateDao;

    /**
     * 发送退费验证码
     * 发送前验证用户有没有退费权限
     * yyt.order.refund.sms.send
     *
     * @param data {"mobile":"","order_no":""}
     * @return
     */
    public Response sendRefundSms(String data) {
        Response response = new Response();
        Map<String, String> map = JsonUtils.parseObject(data, Map.class);
        String mobile = map.get("mobile");
        String orderNo = map.get("order_no");

        if (StringUtils.isBlank(mobile) || StringUtils.isBlank(orderNo)) {
            response.setResultCodeAndMessage("1101", "手机号和订单号不能为空");
            return response;
        }


        Response roleResp = BaseService.callUnderlineFromInternal("yyt.base.role.by.login.name.select", "{\"login_name\":\"" + mobile + "\"}");
        if (!"0".equals(roleResp.getResultCode())) {
            logger.error("查询用户角色失败");
            response.setResultCodeAndMessage("16100", "查询用户角色失败");
            return response;
        }

        List<RoleVo> roleList = JsonUtils.parseArray(roleResp.getResult(), RoleVo.class);
        if (roleList == null || roleList.size() == 0 || !roleList.get(0).getId().equals("64e31161913946198f57c5ec0fa903f2")) {
            response.setResultCodeAndMessage("16101", "用户没有退费的权限");
            return response;
        }

        // 发送短信
        String code = String.valueOf(Math.abs(PKGenerator.generateId().hashCode()));
        int i = code.length();
        if (i < 6) {
            code += "000000";
        }
        code = code.substring(0, 6);
        String msgStr = "{\"user_type\":\"5\",\"to_user\":\"" + mobile
                + "\",\"msg_type\":1,\"msg_content\":{\"code\":\"" + code + "\"}}";
        MessageService.callUnderlineFromInternal("", "yyt.message.msg.sms.send", msgStr);
        Response cacheResponse = CacheService.setGlobalKey("base", "verification_code", mobile + orderNo, code, 120);
        logger.info("获取退费验证码接口, 生成验证码为：" + code + " -- CacheResponse:" + cacheResponse.getResultCode() + "; " + cacheResponse.getResultMessage());
        return response;
    }

    /**
     * 发起退费
     * yyt.order.refund.ack
     * @param data {"mobile":"","order_no":"","validate_code":""}
     * @return
     */
    public Response ackRefund(String data) {
        Response response = new Response();
        Map<String, String> map = JsonUtils.parseObject(data, Map.class);
        String mobile = map.get("mobile");
        String orderNo = map.get("order_no");
        String validateCode = map.get("validate_code");

        if (StringUtils.isBlank(mobile) || StringUtils.isBlank(orderNo) || StringUtils.isBlank(validateCode)) {
            response.setResultCodeAndMessage("16101", "手机号和订单号、验证码不能为空");
            return response;
        }

        //验证码验证
        String verificationCode = CacheService.getGlobalKey("base", "verification_code", mobile + orderNo);
        logger.info("退费接口, 缓存中获取验证码为：" + verificationCode);

        if (StringUtils.isBlank(verificationCode) || !verificationCode.trim().equalsIgnoreCase(validateCode.trim())) {
            response.setResultCodeAndMessage("16101", "验证码不正确");
            return response;
        }

        Map<String, String> dataMap = new HashMap<>();
        dataMap.put("order_no", orderNo);
        Response ordResponse = BaseService.callUnderlineFromInternal("yyt.base.order.by.order.no.out.get", JsonUtils.toJsonString(dataMap));
        if (!"0".equals(ordResponse.getResultCode())) {
            response.setResultCodeAndMessage("3000", "查询订单失败。");
            return response;
        }

        OrderExtVo order = JsonUtils.parseObject(ordResponse.getResult(), OrderExtVo.class);

        if (order.getOrderStatus() == OrderExtVo.ORDER_STATUS_SUCCESS) {
            response.setResultCodeAndMessage("16101", "成功订单不允许退费");
            return response;
        }
        if (order.getOrderStatus() == OrderExtVo.ORDER_PAY_STATUS_REFUNDED) {
            response.setResultCodeAndMessage("16101", "订单已退费");
            return response;
        }

        try {
            OrderRefundValidate validate = new OrderRefundValidate();
            validate.setId(UUIDUtil.get32UUID());
            validate.setOrderNo(orderNo);
            validate.setMobile(mobile);
            validate.setValidateCode(validateCode);
            validate.setCreatedTime(DateUtils.dateToString(new Date()));
            orderRefundValidateDao.insert(validate);
        }catch (Exception e){
            logger.error("保存退费验证码入库失败" + e.getMessage());
            response.setResultCodeAndMessage("16103","保存退费验证码失败");
            return response;
        }

        String method = "yyt.pay.refund.channel.origin";
        Map<String, Object> jsonMap = new HashMap<String, Object>();
        jsonMap.put("order_no", orderNo);
        jsonMap.put("refund_amount", order.getPayAmount());
        jsonMap.put("refund_time", DateUtils.dateToString(new Date()));
        jsonMap.put("refund_reason", "小工具退费");
        jsonMap.put("refund_flag", 1);
        jsonMap.put("push_type", 1);
        logger.info("请求退款系统参数->" + JSON.toJSONString(jsonMap));
        Response payResponse = PayService.callUnderlineFromInternal("", method, JSON.toJSONString(jsonMap));
        logger.info("返回退款新系统参数->" + JSON.toJSONString(payResponse));
        if ("0".equals(payResponse.getResultCode())) {
            response.setResultCodeAndMessage("0","退款成功");
        }else{
            return payResponse;
        }
        return response;
    }


    /**
     * his状态查询
     * yyt.order.refund.his.state.query
     * @param data {"org_code":"szsdsrmyy","order_no":"YRP201709201532280001","medical_card_type":1,"medical_card_no":"0008425437","order_type":1}
     */
    public Response queryRefundHisState(String data) {
        Response response = new Response();
        Map<String,String> requestVo = JsonUtils.parseObject(data, Map.class);

        Map<String, String> dataMap = new HashMap<>();
        dataMap.put("order_no", requestVo.get("order_no"));
        Response ordResponse = BaseService.callUnderlineFromInternal("yyt.base.order.by.order.no.out.get", JsonUtils.toJsonString(dataMap));
        if (!"0".equals(ordResponse.getResultCode())) {
            response.setResultCodeAndMessage("3000", "查询订单失败。");
            return response;
        }

        OrderExtVo order = JsonUtils.parseObject(ordResponse.getResult(), OrderExtVo.class);

        if (StringUtils.isBlank(order.getOrderNo()) || order.getOrderType() ==null) {
            response.setResultCodeAndMessage("16101", "订单类型和订单号不能为空");
            return response;
        }

        if(order.getOrderType() == OrderExtVo.ORDER_TYPE_REGISTER) {
            RegisterExceptionRecordVo registerRecordsVo = new RegisterExceptionRecordVo();
            registerRecordsVo.setHospitalCode(order.getOrgCode());
            registerRecordsVo.setBranchCode(order.getBranchCode());
            registerRecordsVo.setPatCardNo(order.getMedicalCardNo());
            registerRecordsVo.setPatCardType(order.getMedicalCardType() == null ? "1" : String.valueOf(order.getMedicalCardType()));
//        registerRecordsVo.setOrderMode(vo.getPayMode() == null ? "0" : String.valueOf(vo.getPayMode()));
            registerRecordsVo.setOrderMode("0");//orderMode传0 查询所有
            registerRecordsVo.setYytOrdNum(order.getOrderNo());
            ResCommon<RegisterExceptionRecordVoResponse> payResponse = HisifaceService.getHisifaceClient().getRegisterExceptionRecord(registerRecordsVo);

            logger.info("挂号异常单处理,查询订单返回结果, yyt.register.pay.reg.record.confirm response->" + JSON.toJSONString(payResponse));
            if ("0".equals(payResponse.getResultCode())) {
                RegisterExceptionRecordVoResponse recordsVoResponse = payResponse.getResult();
                if (recordsVoResponse != null && JsonUtils.toJsonString(recordsVoResponse).length() > 5) {
//                    if ("2".equals(recordsVoResponse.getStatus())) { // 查询成功，result值不为空，则当成挂号成功，不判断状态，已与存豪确认;
                    response.setResultCodeAndMessageAndResult("0", "订单写单成功，不可退费", JsonUtils.toJsonString(recordsVoResponse));
                    return response;
                } else {// 明确失败，查询成功，result为空，认为写单失败，失败
                    response.setResultCodeAndMessage("0", "订单写单失败，可退费");
                    return response;
                }

            } else {
                response.setResultCodeAndMessage("-1", "订单写单异常，请与HIS确定订单状态");
                return response;
            }
        } else if (order.getOrderType() == OrderExtVo.ORDER_TYPE_CLINIC) { //门诊异常处理
            //查询HIS已缴费信息查询
            PayVo payvo = new PayVo();
            payvo.setHospitalCode(order.getOrgCode());
            payvo.setBranchCode(order.getBranchCode());
            payvo.setPatCardType(ObjectParser.toString(order.getMedicalCardType()));
            payvo.setPatCardNo(order.getMedicalCardNo());
            // 99为海鹚mini付
            payvo.setPayMode(ObjectParser.toString(order.getPayMode().intValue() == 99 ? 23 : order.getPayMode()));
            payvo.setYytOrdNum(order.getOrderNo());
            Map<String, Object> extendMap = new HashMap<String, Object>();
            extendMap.put("his_ord_num", order.getHisOrderNo());// 佛一门诊已缴费记录查询增加参数
            payvo.setExtendParams(JsonUtils.toJsonString(extendMap));
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.MONTH, -1);
            payvo.setBeginDate(DateUtils.getDateStr(calendar.getTime()));
            payvo.setEndDate(DateUtils.getDateStr(new Date()));

            logger.info("请求前置机门诊已缴费查询订单["+order.getOrderNo()+"]request->" + JSONObject.toJSONString(payvo));
            ResCommon<List<PayVoResponse>> payResponse = HisifaceService.getHisifaceClient().listClinicPay(payvo);
            logger.info("请求前置机门诊已缴费查询订单["+order.getOrderNo()+"]reseponse->" + JSON.toJSONString(payResponse));

            if ("0".equals(payResponse.getResultCode())) {
                List<PayVoResponse> payVoResponses= payResponse.getResult();
                if (payVoResponses != null && payVoResponses.size() > 0) {
                    //如果条数大于1，直接返回，不处理
                    if (payVoResponses.size() > 1) {
                        response.setResultCodeAndMessage("-1", "订单写单异常，请与HIS确定订单状态");
                        return response;
                    }
                    //取第一条数据，进行数据的状态校验
                    PayVoResponse payVoResponse =payVoResponses.get(0);
                    if ("1".equals(payVoResponse.getPayStatus())) { // 查询成功，result为值，并且支付状态为已支付，成功
                        response.setResultCodeAndMessageAndResult("0", "订单写单成功，不可退费", JsonUtils.toJsonString(payVoResponse));
                        return response;
                    } else { // 明确失败,查询成功，result为值，但支付状态不是已支付，失败
                        response.setResultCodeAndMessage("0", "订单写单失败，可退费");
                        return response;
                    }
                } else {// 明确失败，查询成功，result为空，认为写单失败，失败
                    response.setResultCodeAndMessage("0", "订单写单失败，可退费");
                    return response;
                }
            }else {
                response.setResultCodeAndMessage("-1", "订单写单异常，请与HIS确定订单状态");
                return response;
            }
        } else if (order.getOrderType() == OrderExtVo.ORDER_TYPE_IN_HOSPITAL) {//住院异常处理
            //查询his住院已缴费信息
            DepositRecordsVo depositVo = new DepositRecordsVo();
            depositVo.setHospitalCode(order.getOrgCode());
            depositVo.setBranchCode(order.getBranchCode());
            depositVo.setPatCardType(ObjectParser.toString(order.getMedicalCardType()));
            depositVo.setPatCardNo(order.getMedicalCardNo());
            depositVo.setPayMode(ObjectParser.toString(order.getPayMode().intValue() == 99 ? 23 : order.getPayMode()));
            depositVo.setYytOrdNum(order.getOrderNo());
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.MONTH, -1);
            depositVo.setBeginDate(DateUtils.getDateStr(calendar.getTime()));
            depositVo.setEndDate(DateUtils.getDateStr(new Date()));
            Map<String, String> extraParamsMap = JsonUtils.parseObject(order.getExtraParams(), Map.class);
            if(extraParamsMap != null) {
                depositVo.setAdmissionNo(extraParamsMap.get("admission_no"));
                Map<String,String> requestExtMap = new HashMap<>();
                requestExtMap.put("patient_id",extraParamsMap.get("patient_id"));
                requestExtMap.put("in_time",extraParamsMap.get("in_time"));
                depositVo.setExtendParams(JsonUtils.toJsonString(requestExtMap));
            }

            logger.info("请求前置机住院已缴费查询订单["+order.getOrderNo()+"]request->" + JSONObject.toJSONString(depositVo));
            ResCommon<List<DepositRecordsVoResponse>> payResponse = HisifaceService.getHisifaceClient().getDepositRecords(depositVo);
            logger.info( "请求前置机住院已缴费查询订单["+order.getOrderNo()+"]response->" + JSONObject.toJSONString(payResponse));
            if ("0".equals(payResponse.getResultCode())) {
                List<DepositRecordsVoResponse> payVoResponses = payResponse.getResult();
                if (payVoResponses != null && payVoResponses.size() > 0) {
                    //如果条数大于1，直接返回，不处理
                    if (payVoResponses.size() > 1) {
                        response.setResultCodeAndMessage("-1", "订单写单异常，请与HIS确定订单状态");
                        return response;
                    }
                    //取第一条数据，进行数据的状态校验
                    DepositRecordsVoResponse payVoResponse = payVoResponses.get(0);
                    response.setResultCodeAndMessage("0", "订单写单成功，不可退费");
                    return response;
                } else {
                    response.setResultCodeAndMessage("0", "订单写单失败，可退费");
                    return response;
                }
            } else {
                response.setResultCodeAndMessage("-1", "订单写单异常，请与HIS确定订单状态");
                return response;
            }
        }

        response.setResultCodeAndMessage("16109","查询失败");
        return response;
    }


}